/*
 * Copyright (C) 2008 ZXing authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.ksy.ksypda.libzxing.zxing.activity;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.graphics.drawable.Drawable;
import android.hardware.Camera;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TextView;

import com.google.zxing.Result;
import com.ksy.ksypda.CodeEvent;
import com.ksy.ksypda.R;
import com.ksy.ksypda.libzxing.zxing.camera.CameraManager;
import com.ksy.ksypda.libzxing.zxing.decode.DecodeThread;
import com.ksy.ksypda.libzxing.zxing.utils.BeepManager;
import com.ksy.ksypda.libzxing.zxing.utils.CaptureActivityHandler;
import com.ksy.ksypda.libzxing.zxing.utils.InactivityTimer;
import com.ksy.ksypda.utils.DensityUtils;

import org.simple.eventbus.EventBus;
import org.simple.eventbus.Subscriber;
import org.simple.eventbus.ThreadMode;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.text.DateFormat;
import java.text.FieldPosition;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;


public final class CaptureActivity extends Activity implements SurfaceHolder.Callback {

    private static final String TAG = CaptureActivity.class.getSimpleName();
    @BindView(R.id.sf_Scan_code_area)
    SurfaceView sfScanCodeArea;
    /*@BindView(R.id.et_scann_content)
    EditText etScannContent;*/
    @BindView(R.id.rl_scann_content)
    RelativeLayout rlScannContent;
    @BindView(R.id.tv_fanhui)
    TextView tvFanhui;
    @BindView(R.id.tv_wancheng)
    TextView tvWancheng;
    @BindView(R.id.ly_scannanniu)
    LinearLayout lyScannanniu;
    @BindView(R.id.lv_scann_content)
    ListView lvScannContent;
    @BindView(R.id.sl_scann_content)
    ScrollView slScannContent;


    //定义一个集合存放每次扫描的结果
    List<String> scanContentList = new ArrayList<>();
    //List<List<String>> scanContentList=new ArrayList<>();
    //声明实体类对象
    CodeEvent codeEvent = new CodeEvent();
    //声明适配器适配扫码数据
    ScanContentAdapter scanContentAdapter;
    private CameraManager cameraManager;
    private CaptureActivityHandler handler;
    private SurfaceView scanPreview = null;
    private InactivityTimer inactivityTimer;

    private BeepManager beepManager;
    private RelativeLayout scanContainer;
    private RelativeLayout scanCropView;
    private ImageView scanLine;
    //ToggleButton//手电筒开启
    private ImageView top;

    private Rect mCropRect = null;
    private boolean isHasSurface = false;
    private Camera camera = null;
    private Camera.Parameters parameters = null;
    private String mMsg;

    public Handler getHandler() {
        return handler;
    }

    public CameraManager getCameraManager() {
        return cameraManager;
    }

    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.activity_capture);
        EventBus.getDefault().register(this);
        ButterKnife.bind(this);
        Window window = getWindow();
        window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        controlIconSize();
        initView();
        scanContentAdapter = new ScanContentAdapter();
//        camera = CameraManager.getCamera();
//        Log.d("相机实例", camera + "");
    }

    private void initView() {
        scanPreview = findViewById(R.id.sf_Scan_code_area);
        scanContainer = findViewById(R.id.capture_container);
        scanCropView = findViewById(R.id.capture_crop_view);
        scanLine = findViewById(R.id.capture_scan_line);
        top = findViewById(R.id.capture_mask_top);
        inactivityTimer = new InactivityTimer(this);
        beepManager = new BeepManager(this);


        TranslateAnimation animation = new TranslateAnimation(Animation.RELATIVE_TO_PARENT, 0.0f, Animation
                .RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT,
                0.9f);
        animation.setDuration(1800);
        animation.setRepeatCount(-1);
        animation.setRepeatMode(Animation.RESTART);
        scanLine.startAnimation(animation);

        //取消弹出软键盘
        //etScannContent.setInputType(InputType.TYPE_NULL);
        //水平滚动设置为False
        //etScannContent.setHorizontallyScrolling(true);
        //设置EditText的显示方式为多行文本输入
        //etScannContent.setInputType(InputType.TYPE_TEXT_FLAG_MULTI_LINE);

    }

    private void controlIconSize() {
        //initDrawable(mOpenFlashLight);
    }

    private void init() {
        Intent intent = getIntent();
        if (intent != null) {
            mMsg = intent.getStringExtra("msg");
        }

        /*mOpenFlashLight.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
                //低于6.0系统的手电筒
                if (isChecked) {
                    //camera和手电筒共同使用的是camera的单例模式
                    camera = CameraManager.getCamera();
                    parameters = camera.getParameters();
                    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);// 开启
                    camera.setParameters(parameters);
                } else {
                    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);// 关闭
                    camera.setParameters(parameters);
                }
            }
        });*/

    }

    @Override
    protected void onResume() {
        super.onResume();
//        init();
        cameraManager = new CameraManager(getApplication());
        handler = null;
        if (isHasSurface) {
            initCamera(scanPreview.getHolder());
        } else {
            scanPreview.getHolder().addCallback(this);
        }
        inactivityTimer.onResume();
    }

    //使Zxing能够继续扫描
    public void continuePreview() {
        if (handler != null) {
            handler.restartPreviewAndDecode();
        }
    }

    @Override
    protected void onPause() {
        if (handler != null) {
            handler.quitSynchronously();
            handler = null;
        }
        inactivityTimer.onPause();
        beepManager.close();
        cameraManager.closeDriver();
        if (!isHasSurface) {
            scanPreview.getHolder().removeCallback(this);
        }
        super.onPause();
    }

    @Override
    protected void onDestroy() {
        inactivityTimer.shutdown();
        EventBus.getDefault().unregister(this);
        super.onDestroy();
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        if (holder == null) {
            Log.e(TAG, "*** WARNING *** surfaceCreated() gave us a null surface!");
        }
        if (!isHasSurface) {
            isHasSurface = true;
            initCamera(holder);
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        isHasSurface = false;
        cameraManager.stopPreview();
//        //主要在这里实现Camera的释放
//        if (camera != null) {
//            camera.release();
//            camera = null;
//        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    //扫描解析结果
    public void handleDecode(Result rawResult, final Bundle bundle) {
        inactivityTimer.onActivity();
        beepManager.playBeepSoundAndVibrate();
        Log.d("这里", bundle.getByteArray(DecodeThread.BARCODE_BITMAP) + "");
        saveFileWithByte(bundle.getByteArray(DecodeThread.BARCODE_BITMAP));
        final String rawResultText = rawResult.getText();
        Log.d("rawResultText", rawResultText);
        List<CodeEvent> list = new ArrayList<CodeEvent>();
        CodeEvent codeEvent = new CodeEvent();
        codeEvent.setCode(rawResultText);
        list.add(codeEvent);
        for (CodeEvent co : list) {
            Log.d("扫描结果在这里", rawResultText + "\n" + scanContentList.contains(co.getCode()));
            if (!scanContentList.contains(co.getCode())) {
                scanContentList.add(co.getCode());
                scanContentAdapter.notifyDataSetChanged();
            }
        }
        //给listview添加数据
        lvScannContent.setAdapter(scanContentAdapter);
        EventBus.getDefault().post(new CodeEvent(rawResultText), "code");
//        getPreViewImage();
        //开启线程 执行连续扫描
        new Handler().postDelayed(new Runnable() {
            public void run() {
                SurfaceHolder surfaceHolder = sfScanCodeArea.getHolder();
                initCamera(surfaceHolder);
                continuePreview();
            }

        }, 3000);
    }

    //显示扫描结果
    @Subscriber(tag = "picture", mode = ThreadMode.MAIN)
    private void receiveFromCap(Bitmap info) {
        Log.d("图片", info + "");
        //控件显示文本
        top.setImageBitmap(info);
//
    }

    //保存图片的方法
    public static void saveFileWithByte(final byte[] bytes) {
        //定义路径
        String filePath = Environment.getExternalStorageDirectory() + "/myImages/";
        File localFile = new File(filePath);
        if (!localFile.exists()) {
            localFile.mkdir();
        }
        //定义文件名
        File file = new File(localFile, System.currentTimeMillis() + ".jpg");
        FileOutputStream outputStream = null;
        BufferedOutputStream bufferedOutputStream = null;
        try {
            if (file.exists()) {
                file.delete();
            }
            file.createNewFile();
            outputStream = new FileOutputStream(file);
            bufferedOutputStream = new BufferedOutputStream(outputStream);
            bufferedOutputStream.write(bytes);
            bufferedOutputStream.flush();

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //在finally块中关闭流
            try {
                if (outputStream != null) {
                    outputStream.close();
                }
                if (bufferedOutputStream != null) {
                    bufferedOutputStream.close();

                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }


    private void initCamera(SurfaceHolder surfaceHolder) {
        if (surfaceHolder == null) {
            throw new IllegalStateException("No SurfaceHolder provided");
        }
        if (cameraManager.isOpen()) {
            Log.w(TAG, "initCamera() while already open -- late SurfaceView callback?");
            return;
        }
        try {
            cameraManager.openDriver(surfaceHolder);
            // Creating the handler starts the preview, which can also throw a
            // RuntimeException.
            if (handler == null) {
                handler = new CaptureActivityHandler(this, cameraManager, DecodeThread.ALL_MODE);
            }

            initCrop();
        } catch (IOException ioe) {
            Log.w(TAG, ioe);
//            displayFrameworkBugMessageAndExit();
        } catch (RuntimeException e) {
            // Barcode Scanner has seen crashes in the wild of this variety:
            // java.?lang.?RuntimeException: Fail to connect to camera service
            Log.w(TAG, "Unexpected error initializing camera", e);
//            displayFrameworkBugMessageAndExit();
        }
    }

    private void displayFrameworkBugMessageAndExit() {
        // camera error
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(getString(R.string.app_name));
        builder.setMessage("请允许打开摄像头");
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                finish();
            }

        });
        builder.setOnCancelListener(new DialogInterface.OnCancelListener() {

            @Override
            public void onCancel(DialogInterface dialog) {
                finish();
            }
        });
        builder.show();
    }

    public void restartPreviewAfterDelay(long delayMS) {
        if (handler != null) {
            handler.sendEmptyMessageDelayed(R.id.restart_preview, delayMS);
        }
    }

    public Rect getCropRect() {
        return mCropRect;
    }

    //初始化截取的矩形区域
    private void initCrop() {
        int cameraWidth = cameraManager.getCameraResolution().y;
        int cameraHeight = cameraManager.getCameraResolution().x;

        /** 获取布局中扫描框的位置信息 */
        int[] location = new int[2];
        scanCropView.getLocationInWindow(location);

        int cropLeft = location[0];
        int cropTop = location[1] - getStatusBarHeight();

        int cropWidth = scanCropView.getWidth();
        int cropHeight = scanCropView.getHeight();

        /** 获取布局容器的宽高 */
        int containerWidth = scanContainer.getWidth();
        int containerHeight = scanContainer.getHeight();

        /** 计算最终截取的矩形的左上角顶点x坐标 */
        int x = cropLeft * cameraWidth / containerWidth;
        /** 计算最终截取的矩形的左上角顶点y坐标 */
        int y = cropTop * cameraHeight / containerHeight;

        /** 计算最终截取的矩形的宽度 */
        int width = cropWidth * cameraWidth / containerWidth;
        /** 计算最终截取的矩形的高度 */
        int height = cropHeight * cameraHeight / containerHeight;

        /** 生成最终的截取的矩形 */
        mCropRect = new Rect(x, y, width + x, height + y);
    }

    private int getStatusBarHeight() {
        try {
            Class<?> c = Class.forName("com.android.internal.R$dimen");
            Object obj = c.newInstance();
            Field field = c.getField("status_bar_height");
            int x = Integer.parseInt(field.get(obj).toString());
            return getResources().getDimensionPixelSize(x);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    //将TextView中的图片转化为规定大小的方法
    public void initDrawable(TextView v) {
        Drawable drawable = v.getCompoundDrawables()[1];
        drawable.setBounds(0, 0, DensityUtils.dp2px(CaptureActivity.this, 50), DensityUtils.dp2px(CaptureActivity.this, 50));
        v.setCompoundDrawables(null, drawable, null, null);
    }

    @OnClick(R.id.tv_fanhui)
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.tv_fanhui:
                finish();
                break;
        }
    }

    public class ScanContentAdapter extends BaseAdapter {

        @Override
        public int getCount() {
            Log.d("数量", String.valueOf(scanContentList.size()));
            return scanContentList.size();
        }

        @Override
        public Object getItem(int position) {
            return position;
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup viewGroup) {
            ViewHolder viewHolder;
            if (convertView == null) {
                convertView = View.inflate(CaptureActivity.this, R.layout.scancontent, null);
                viewHolder = new ViewHolder();
                viewHolder.tvScanContent = (TextView) convertView.findViewById(R.id.tv_scan_content);
                convertView.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder) convertView.getTag();
            }
            final String codeEvent = scanContentList.get(position);
            viewHolder.tvScanContent.setText(codeEvent.toString());
            return convertView;
        }

        private class ViewHolder {
            TextView tvScanContent;
        }
    }

    private void getPreViewImage() {

        camera.setPreviewCallback(new Camera.PreviewCallback() {

            @Override
            public void onPreviewFrame(byte[] data, Camera camera) {
                Camera.Size size = camera.getParameters().getPreviewSize();
                try {
                    YuvImage image = new YuvImage(data, ImageFormat.NV21, size.width, size.height, null);
                    if (image != null) {
                        ByteArrayOutputStream stream = new ByteArrayOutputStream();
                        image.compressToJpeg(new Rect(0, 0, size.width, size.height), 80, stream);
                        Bitmap bmp = BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size());
                        //**********************
                        //因为图片会放生旋转，因此要对图片进行旋转到和手机在一个方向上
                        rotateMyBitmap(bmp);
                        //**********************************
                        stream.close();
                    }
                } catch (Exception ex) {
                    Log.e("Sys", "Error:" + ex.getMessage());
                }
            }
        });
    }

    public void rotateMyBitmap(Bitmap bmp) {
        //*****旋转一下
        Matrix matrix = new Matrix();
        matrix.postRotate(90);

        Bitmap bitmap = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), Bitmap.Config.ARGB_8888);

        Bitmap nbmp2 = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true);
        //*******显示一下
        top.setImageBitmap(nbmp2);
    }


}